package com.tywj.panda.home.buy

import android.graphics.BitmapFactory
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.amap.api.maps.AMap
import com.amap.api.maps.AMap.OnMarkerClickListener
import com.amap.api.maps.model.*
import com.amap.api.maps.utils.overlay.SmoothMoveMarker
import com.amap.api.navi.AmapNaviPage
import com.amap.api.navi.AmapNaviParams
import com.amap.api.navi.AmapNaviType
import com.amap.api.navi.AmapPageType
import com.amap.api.services.core.AMapException
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.route.*
import com.amap.api.services.route.RouteSearch.*
import com.bigkoo.pickerview.builder.OptionsPickerBuilder
import com.bigkoo.pickerview.listener.OnOptionsSelectListener
import com.bigkoo.pickerview.view.OptionsPickerView
import com.tywj.lib.core.common.extension.*
import com.tywj.lib.core.common.util.BarUtil
import com.tywj.lib.core.common.util.JsonUtil
import com.tywj.lib.core.common.util.LogUtil
import com.tywj.lib.core.common.util.ResourcesUtil
import com.tywj.lib.lifecycle.extension.attachToLifecycle
import com.tywj.lib.location.entity.LocationEntity
import com.tywj.lib.route.RouteParam
import com.tywj.navigation.base.BaseMapActivity
import com.tywj.navigation.entity.DrivingRouteOverlay
import com.tywj.navigation.entity.GPSEntity
import com.tywj.navigation.popupwindow.MapDetailsPopUpImgView
import com.tywj.navigation.popupwindow.NavigationPopupWindow
import com.tywj.navigation.tool.MapTool
import com.tywj.panda.customer.common.entity.HomeLineDetailsEntity
import com.tywj.panda.customer.common.http.PDArrayCallback
import com.tywj.panda.customer.common.http.PDObjectCallback
import com.tywj.panda.customer.common.tool.*
import com.tywj.panda.home.R
import com.tywj.panda.home.api.HomeApi
import com.tywj.panda.home.details.HomeLineDetailsAdapter
import com.tywj.panda.home.details.ShareDialog
import com.tywj.panda.home.entity.GPSAddressEntity
import com.tywj.panda.home.entity.HomeLineEntity
import com.tywj.panda.home.entity.HomeLineTimeEntity
import com.tywj.panda.home.event.HomeEvent
import com.tywj.panda.home.route.HomeRoute
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.home_activity_line_details.*
import java.util.concurrent.TimeUnit

/**
 * <pre>
 *     author : June Yang
 *     time   : 2020/05/22
 *     desc   : 线路详情界面
 *     version: 1.0.0
 * </pre>
 */
@Route(path = HomeRoute.HOME_LINE_DETAILS)
class HomeLineDetailsActivity : BaseMapActivity() {

    companion object {
        const val PARAMS_HOME_LINE_DATA = "params_home_data"
    }

    private lateinit var mAdapter: HomeLineDetailsAdapter

    // 是否是第一次获取定位
    private var isFirstLocation = false

    private var routeSearch: RouteSearch? = null

    //是否显示
    private var isShowDetails = false

    private var lineCode = ""
    private var lineName = ""
    private var clickMarker: Marker? = null

    //记录先前设置的起点或终点的位置
    private var preSetStartStation = -1
    private var preSetEndStation = -1


    //站点
    private var stations = ArrayList<HomeLineDetailsEntity.Station>()

    //最终选择的出发起始站点
    private var upStations = ArrayList<HomeLineDetailsEntity.Station>(2)

    //途径点坐标
    private var listRoute = ArrayList<ArrayList<Double>>()


    private var homeLineEntity: HomeLineEntity.DataBean? = null

    // 预约时间数据
    private val timeList = ArrayList<String>()

    //发车时间
    private var lineTimeSelected = ""

    //记录当前选择的班次时间位置，防止多次查询相同的数据
    private var mPreTimePosition = -1

    /**
     * 分享弹窗
     */
    private val shareDialog by lazy { initShareDialog() }

    //预约时间选择器
    private lateinit var appointmentTimePickerView: OptionsPickerView<String>

    //当前位置
    private var currentLocation: LocationEntity? = null

    //车辆平滑移动
    private var moveMarker: SmoothMoveMarker? = null
    private var movePath = ArrayList<LatLng>()

    //记录标记点
    private var listMaker = ArrayList<Marker>()

    //定时刷新车辆GPS轨迹
    private var intervalRefreshDisposable: Disposable? = null


    override fun getLayoutID(): Int = R.layout.home_activity_line_details

    override fun initVariable(savedInstanceState: Bundle?) {
        super.initVariable(savedInstanceState)

        homeLineEntity = RouteParam(this).getParcelable(PARAMS_HOME_LINE_DATA)
        homeLineEntity?.let {
            lineCode = it.lineInfoId
            tvPrice.text = MoneyTool.formatFen(it.price)
            lineName = it.name
            tvTravelLineName.text = lineName
            tvStatAndEndStation.text = it.fiedName
        }
    }

    override fun initView(savedInstanceState: Bundle?) {
        super.initView(savedInstanceState)
        BarUtil.setStatusBarColor(this, ResourcesUtil.getColor(com.tywj.panda.customer.usercenter.R.color.common_white))
        BarUtil.setStatusBarLightMode(this.window, true)

        initRecyclerView()
        initTimePickerView()
//        initMap()
    }


    override fun initListener() {
        super.initListener()

        titleLayout.getRightImageButton().onClick {

            shareDialog.showDialog(supportFragmentManager)
        }

        //订单生成后关闭当前界面
        HomeEvent.colseHomeServiceEvent.observe(this, Observer {
            finish()
        })

        tvBusTimeList.onClick {
            //弹出班次表 适配器的数据再添加后出现在界面上
            appointmentTimePickerView.show()
        }

        btnBuy.onClick {
            LogoutTool.checkLoginStatus(this) {

                if (preSetStartStation < preSetEndStation) {

                    HomeRoute.toBuyTickets(
                        lineCode = lineCode,
                        lineName = lineName,
                        selectedTimeIndex = if (mPreTimePosition == -1) {
                            0
                        } else {
                            mPreTimePosition
                        },
                        endStationPos = preSetEndStation,
                        stationsList = stations
                    )
                        .navigation(this)
                } else {
                    HomeRoute.toBuyTickets(
                        lineCode = lineCode,
                        lineName = lineName,
                        selectedTimeIndex = if (mPreTimePosition == -1) {
                            0
                        } else {
                            mPreTimePosition
                        },
                        startStationPos = preSetEndStation,
                        endStationPos = preSetStartStation,
                        stationsList = stations
                    )
                        .navigation(this)
                }
            }
        }

        ivMapUp.onClick {
            isShowDetails = !isShowDetails
            RotateUtils.rotateArrow(ivMapUp, isShowDetails)
            if (isShowDetails) {
                visible(viewSpace, rvMapList)
            } else {
                gone(viewSpace, rvMapList)
            }
        }

        mAdapter.setOnItemChildClickListener { _, view, position ->

            val bean = mAdapter.data[position]

            when (view.id) {

                //是否扩展
                R.id.tvAddress -> {
                    bean.isExpanded = !bean.isExpanded

                    mAdapter.notifyItemChanged(
                        position + mAdapter.headerLayoutCount,
                        HomeLineDetailsAdapter.UPDATE_TYPE_STATION_STATUS
                    )
                }

                //设置为起点
                R.id.tvSetStartPoint -> {

                    if (position == mAdapter.data.size - 1) {
                        shortToast(R.string.home_cannot_set_to_start)
                        return@setOnItemChildClickListener
                    }

                    shortToast(R.string.home_had_set_start)
                    //起点的位置只有一个
                    preSetStartStation = position

                    for (bean in mAdapter.data) {
                        bean.isTagStartStation = false
                    }
                    bean.isTagStartStation = true

                    mAdapter.notifyDataSetChanged()

                }
                //设置为终点
                R.id.tvSetEndPoint -> {

                    if (position == 0) {
                        shortToast(R.string.home_cannot_set_to_end)
                        return@setOnItemChildClickListener
                    }

                    shortToast(R.string.home_had_set_end)
                    //终点的位置只有一个
                    preSetEndStation = position
                    for (bean in mAdapter.data) {
                        bean.isTagEndStation = false
                    }
                    bean.isTagEndStation = true

                    mAdapter.notifyDataSetChanged()
                }
            }
        }

        statusLayout.setOnEmptyLayoutButtonClick {
            loadDataBusTimeList()
        }
        statusLayout.setOnErrorLayoutButtonClick {
            loadDataBusTimeList()
        }

        map.setInfoWindowAdapter(object : AMap.InfoWindowAdapter {
            var infoWindow: View? = null

            override fun getInfoContents(marker: Marker?): View {
                return View(this@HomeLineDetailsActivity)
            }

            override fun getInfoWindow(marker: Marker): View {
                if (infoWindow == null) {
                    infoWindow = LayoutInflater.from(this@HomeLineDetailsActivity)
                        .inflate(R.layout.navigation_map_infiwindow_layout, null)
                }

                infoWindow?.let {
                    render(marker, it)
                }

                return infoWindow!!

            }
        })

        map.setOnMarkerClickListener(OnMarkerClickListener { marker ->
            if (marker.title != null && marker.title != "") {
                clickMarker = marker
                clickMarker?.showInfoWindow()
            }
            true
        })

        map.setOnMapClickListener {
            if (clickMarker != null && clickMarker!!.isInfoWindowShown) {
                clickMarker!!.hideInfoWindow()
                clickMarker = null
            }
        }


    }

    override fun loadDataOnCreate() {
        super.loadDataOnCreate()
        loadDataBusTimeList()
    }

    private fun loadDataStations() {
        statusLayout.showLoadingLayout()
        HomeApi.getCRMLineDetails(lineCode).attachToLifecycle(this)
            .execute(object : PDObjectCallback<HomeLineDetailsEntity>(
                HomeLineDetailsEntity::class.java
            ) {
                override fun success(data: HomeLineDetailsEntity) {

                    statusLayout.showContentLayout()
                    visible(llBuy)
                    handData(data)
                }

                override fun error(code: Int, message: String) {
                    super.error(code, message)
                    statusLayout.showErrorLayoutByCode(code, message)
                    gone(llBuy)
                }
            })
    }

    private fun initRecyclerView() {
        mAdapter = HomeLineDetailsAdapter()

        with(rvMapList) {
            adapter = mAdapter
            layoutManager = LinearLayoutManager(this@HomeLineDetailsActivity)
        }
    }


    override fun onStart() {
        super.onStart()
        PermissionTool.location(this) {}
    }

    override fun onResume() {
        super.onResume()

        //开始轮询车辆轨迹GPS
        intervalRefreshDisposable = refreshBusGPSRoute()
    }

    override fun onStop() {
        super.onStop()

        intervalRefreshDisposable?.safeDisposable()
    }


    private fun handData(data: HomeLineDetailsEntity) {
        stations.clear()

        //拼接站点信息
        stations.add(data.start)
        stations.addAll(data.ways)
        stations.add(data.end)

        listRoute = data.route

        upStations.add(stations.first())
        upStations.add(stations.last())

        refreshBusTimeList()
    }

    //根据用户选择的班次时刻表 同步显示每站的时间表(stations中处理站点信息的时间点 站点之间需要累加实现总时间)
    private fun refreshBusTimeList() {

        var totalTime = 0

        stations.forEachIndexed { index, station ->
            for (i in 0..index) {
                if (i == index) {
                    totalTime += station.time
//                    LogUtil.d("当前第$index" + "值为" + station.time + ",当前时间总和 :$totalTime")
                    break
                }
            }
            station.timeAdd = TimeTool.formatTimeAdd(lineTimeSelected, totalTime.toString())
        }

        mAdapter.setNewData(stations)

        startRouteSearch()
    }

    override fun onMyLocationChange(location: LocationEntity) {
        super.onMyLocationChange(location)

        if (!isFirstLocation) {
            // 第一次获取定位数据，将地址显示到该位置
            isFirstLocation = true
            currentLocation = location
            currentLocation?.let {
                toLocation(it.latitude, it.longitude, MapTool.ZOOM_LEVEL_DEFAULT)
            }
        }
    }

    /**
     * 开始路径规划
     * 驾车出行路线规划
     * https://lbs.amap.com/api/android-sdk/guide/route-plan/drive/#t6
     */

    private fun startRouteSearch() {
        //第一步
        routeSearch = RouteSearch(this)

        /**
         * 第二步
         * 设置数据回调监听器
         * 驾车出行路线规划
         * 高德接口链接：https://lbs.amap.com/api/android-sdk/guide/route-plan/drive
         */
        routeSearch?.setRouteSearchListener(object : OnRouteSearchListener {
            override fun onBusRouteSearched(busRouteResult: BusRouteResult, i: Int) {

            }

            /**
             * 第五步 接受数据
             *
             *
             */
            override fun onDriveRouteSearched(driveRouteResult: DriveRouteResult, rCode: Int) {

                if (rCode == AMapException.CODE_AMAP_SUCCESS) {
                    if (driveRouteResult.paths != null) {
                        val drivePath = driveRouteResult.paths[0] ?: return
                        val drivingRouteOverlay = DrivingRouteOverlay(
                            this@HomeLineDetailsActivity, map, drivePath,
                            driveRouteResult.startPos,
                            driveRouteResult.targetPos, null, stations.first(), stations.last()
                        )
                        drivingRouteOverlay.setNodeIconVisibility(false) //设置节点marker是否显示
                        drivingRouteOverlay.setIsColorfulline(true) //是否用颜色展示交通拥堵情况，默认true
                        drivingRouteOverlay.removeFromMap()
                        drivingRouteOverlay.addToMap()
                        drivingRouteOverlay.zoomToSpan()

//                        startMoveCar(drivePath)
                    }
                }
            }

            override fun onWalkRouteSearched(walkRouteResult: WalkRouteResult, i: Int) {}
            override fun onRideRouteSearched(rideRouteResult: RideRouteResult, i: Int) {}
        })


        val start = LatLonPoint(upStations[0].loc.last(), upStations[0].loc.first())
        val end = LatLonPoint(upStations[1].loc.last(), upStations[1].loc.first())

        val fromAndTo = FromAndTo(start, end)

        val latLonPoints: MutableList<LatLonPoint> = ArrayList()

        val markerOption = MarkerOptions()
        markerOption.draggable(false) //设置Marker可拖动

        markerOption.icon(
            BitmapDescriptorFactory.fromBitmap(
                BitmapFactory.decodeResource(resources, R.drawable.jing)
            )
        )
        // 将Marker设置为贴地显示，可以双指下拉地图查看效果
        markerOption.isFlat = true //设置marker平贴地图效果

        for (i in 1 until stations.size - 1) {
            val latLng = LatLng(stations[i].loc[1], stations[i].loc[0])
            markerOption.title(stations[i].name)
            markerOption.snippet("预计到达：" + stations[i].timeAdd + "？" + stations[i].img + "？" + stations[i].info)
            map.addMarker(markerOption.position(latLng))
        }

        //listRoute 二维数组遍历 途径点数据
        listRoute.forEach {
            //注意经纬度的顺序 移动端SDK经纬度的格式为‘纬度,经度’。
            val point = LatLonPoint(it.last(), it.first())
            latLonPoints.add(point)
        }

        /**
         * 第三步
         *设置搜索参数
         * fromAndTo包含路径规划的起点和终点，
         * drivingMode表示驾车模式  //返回的结果会优先考虑高速路，并且会考虑路况躲避拥堵，与高德地图的“躲避拥堵&高速优先”策略一致
         * 第三个参数表示途经点（最多支持16个），第四个参数表示避让区域（最多支持32个），第五个参数表示避让道路
         */
        val query = DriveRouteQuery(
            fromAndTo,
            DRIVING_SINGLE_DEFAULT,
            latLonPoints,
            null,
            ""
        )
        /**
         * 第四步：发送请求
         */
        routeSearch?.calculateDriveRouteAsyn(query)
    }


    private fun render(marker: Marker, view: View) {
        val time = view.findViewById<TextView>(R.id.time)
        val name = view.findViewById<TextView>(R.id.name)
        val photo = view.findViewById<TextView>(R.id.tvSeeReal)
        val daohang = view.findViewById<TextView>(R.id.tvNavigation)
        val infos = marker.snippet.split("？").toTypedArray()
        time.text = infos[0]
        name.text = marker.title

        photo.setOnClickListener {
            if (marker.title != null && marker.title != "") {

                val path = marker.snippet.split("？").toTypedArray()[1]
                val info = marker.snippet.split("？").toTypedArray()[2]

                LogUtil.d("图片地址:$path")
                if (path.isNotEmpty()) {
                    val mpopUpWindows =
                        MapDetailsPopUpImgView(this, path, info)
                    mpopUpWindows.show()
                } else {
                    shortToast("暂无站点图片")
                }
            }
        }
        val popupWindow = NavigationPopupWindow(this, marker.position)

        popupWindow.goHereListener {
            currentLocation?.let {
                toStartNavigation(it, marker.position)
            }

        }
        daohang.setOnClickListener { v ->
            popupWindow.showAtDropDownCenter(v)

        }
    }


    private fun initShareDialog(): ShareDialog {
        return supportFragmentManager.findFragmentByTag(ShareDialog.TAG) as? ShareDialog
            ?: ShareDialog()
    }

    private fun initTimePickerView() {
        val timeOptions = OptionsPickerBuilder(this, OnOptionsSelectListener { options1, options2, _, _ ->

            if (mPreTimePosition == options1) {
                return@OnOptionsSelectListener
            }
            mPreTimePosition = options1
            val time = timeList[options1]
            lineTimeSelected = time

            //选择时间后重新计算时刻表时间
            refreshBusTimeList()


        }).setTitleColor(ResourcesUtil.getColor(com.tywj.navigation.R.color.common_black_33))
            .setTitleSize(20)
            .setCancelColor(ResourcesUtil.getColor(com.tywj.navigation.R.color.common_gray_B2))
            .setSubCalSize(16)
            .setSubmitColor(ResourcesUtil.getColor(com.tywj.navigation.R.color.common_yellow_FD))
            .setSubCalSize(16)
            .build<String>()
        timeOptions.setNPicker(timeList, null, null)
        timeOptions.setSelectOptions(0, 0, 0)
        appointmentTimePickerView = timeOptions
    }

    //加载班次时刻表
    private fun loadDataBusTimeList() {
        statusLayout.showLoadingLayout()
        HomeApi.getLineTimeByDate(lineCode).attachToLifecycle(this)
            .execute(object : PDArrayCallback<HomeLineTimeEntity>(HomeLineTimeEntity::class.java) {
                override fun success(data: ArrayList<HomeLineTimeEntity>) {
                    handleBusTimeListData(data)
                }

                override fun error(code: Int, message: String) {
                    super.error(code, message)
                    statusLayout.showErrorLayoutByCode(code, message)
                }
            })
    }

    private fun handleBusTimeListData(data: ArrayList<HomeLineTimeEntity>) {

        if (data.isNotEmpty()) {
            //获取站点信息
            loadDataStations()
        } else {
            statusLayout.showEmptyLayout()
            return
        }
        timeList.clear()
        data.forEach {
            if (it.lineTime.isNotEmpty()) {
                timeList.add(it.lineTime)
            }
        }
        lineTimeSelected = timeList.first()

        tvTimeTips.text = String.format(
            ResourcesUtil.getString(R.string.home_line_details_start_and_time),
            timeList.first(),
            timeList.last()
        )
    }

    private fun toStartNavigation(start: LocationEntity, end: LatLng) {
        val mStart = Poi("我的位置", LatLng(start.latitude, start.longitude), "")
        val mEnd = Poi("终点位置", LatLng(end.latitude, end.longitude), "")

        AmapNaviPage.getInstance().showRouteActivity(
            this,
            AmapNaviParams(mStart, null, mEnd, AmapNaviType.DRIVER, AmapPageType.NAVI),
            null
        )
    }


    private fun initMap() {
        //添加marker
        if (moveMarker == null) {
            moveMarker = SmoothMoveMarker(map)
            moveMarker?.setDescriptor(BitmapDescriptorFactory.fromResource(R.drawable.navigation_icon_bus))
        }
    }

    /**
     *
     * https://lbs.amap.com/api/android-sdk/guide/draw-on-map/smooth-move/?sug_index=0
     */
    private fun startMoveCar(drivePath: DrivePath) {
        movePath.clear()

        for (i in drivePath.steps.indices) {
            val path = drivePath.steps[i].polyline

            for (j in path.indices) {
                movePath.add(LatLng(path[j].latitude, path[j].longitude))
            }
        }
        moveMarker?.apply {
            setPoints(movePath)
            setTotalDuration(20)
            startSmoothMove()
        }
    }

    private fun markerBusPoint(list: ArrayList<ArrayList<Double>>) {
        if (list.isEmpty()) return
        //标记前 先清除标记再绘制新的标记点
        listMaker.forEach {
            if (it.title == "car") {
                it.remove()
            }
        }
        list.forEach {
            val markerOption = MarkerOptions()
            val latLng = LatLng(it.last(), it.first())
            //设置Marker覆盖物的位置坐标。
            markerOption.position(latLng)
            //设置 Marker覆盖物 的标题 区分经过点的标记
            markerOption.title("car")
            markerOption.icon(
                BitmapDescriptorFactory.fromBitmap(
                    BitmapFactory.decodeResource(
                        ResourcesUtil.resources,
                        R.drawable.navigation_icon_marker_bus
                    )
                )
            )
            val marker = map.addMarker(markerOption.position(latLng))
            listMaker.add(marker)
        }
    }

    //轮询获取车辆经纬度
    private fun getGpsRoute(lineCode: String) {
        HomeApi.getGpsRoute(lineCode).attachToLifecycle(this)
            .execute(object : PDArrayCallback<GPSEntity>(
                GPSEntity::class.java
            ) {
                override fun success(data: ArrayList<GPSEntity>) {
                    handGPSData(data)
                    LogUtil.d("get gps route success")
                }

                override fun error(code: Int, message: String) {
                    super.error(code, message)
                    LogUtil.d("get gps route fail:$message")
                }
            })
    }

    private fun handGPSData(list: ArrayList<GPSEntity>) {
        if (list.isEmpty()) return
        val gpsList = ArrayList<ArrayList<Double>>()

        list.forEach {
            gpsList.add(it.loc)
        }
        //组成一个二维数组
        markerBusPoint(gpsList)
    }

    private fun refreshBusGPSRoute(): Disposable? {
        val disposable = Observable.interval(0, 10, TimeUnit.SECONDS).applyScheduler(
        ).subscribe({

            if (lineCode.isNotEmpty()) {
                getGpsRoute(lineCode)
            }

        }, {
            LogUtil.printStackTrace(it)
        })
        disposable.attachToLifecycle(this)
        return disposable
    }
}
